/*
 * Copyright (C) 2006 Roman Krashanitsa
 *
 * @author Roman Krashanitsa
 *
 * This file is part of paparazzi.
 *
 * paparazzi is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * paparazzi is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with paparazzi; see the file COPYING.  If not, write to
 * the Free Software Foundation, 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA. 
 *
 */

package pprz.data_components;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;

import pprz.data_components.events.DataEvent;
import pprz.data_components.events.DataEventListener;

public class LogPlayerDevice extends Device {

	protected int message_rate=300; //message input rate msg/sec
	protected RandomAccessFile in;
	protected Worker worker;
	protected Thread thread;
	
	private class Worker implements Runnable {
		boolean stop=false;
		boolean is_running=false;
		LogPlayerDevice owner;
		
		public Worker(LogPlayerDevice owner)
		{this.owner=owner;}
		
		
		
		public void run(){
			stop=false;
			is_running=true;
			long newVal=0;
			long oldVal=0;
			String s=new String();
			while (!stop)
			{
				try {
					Thread.sleep(1000/message_rate);
				} catch (InterruptedException e) {}
				synchronized(this)
				{				
				try {

						s=in.readLine();
				} catch (IOException e) {System.out.println("End of stream");}
				//System.out.println(s);
				if (s!=null)
				try {
					fireDataEvent(new DataEvent(this.owner,s.getBytes("US-ASCII")));
				} catch (UnsupportedEncodingException e) {}
				}

				try {
					newVal=in.getChannel().position()*100/in.getChannel().size();
				} catch (IOException e) {System.out.println("File error");}
				//System.out.println(s);

				if (newVal>oldVal) { 
					owner.firePropertyChangeEvent("progress", oldVal, newVal);
					oldVal=newVal;
				}
			}
			is_running=false;
		}
		
		public void stopCond() {stop=true;}
	}

	public LogPlayerDevice()
	{
		portName=null;
		in=null;
		worker=null;
	}
	
	/* (non-Javadoc)
	 * @see pprz.data_components.Device#setPortName(java.lang.String)
	 */
	@Override
	public void setPortName(String name) {
		super.setPortName(name);
		try {
			in=new RandomAccessFile(name,"r");
//			reader=new BufferedReader(new InputStreamReader(in));
			worker=new Worker(this);
		} catch (FileNotFoundException e)
		{
			System.out.println("File "+name+" is not found..");
		}		
		
	}

	public void init()   
	{
		super.init();
		this.run();
	}
	
    // This protected class is used to fire DataEvents
    void fireDataEvent(DataEvent evt) {
        Object[] listeners = listenerList.getListenerList();
        // Each listener occupies two elements - the first is the listener class
        // and the second is the listener instance
        for (int i=0; i<listeners.length; i+=2) {
            if (listeners[i]==DataEventListener.class) {
                ((DataEventListener)listeners[i+1]).dataEvent(evt);
            }
        }
    }
    
    public void run() 
    {
		if (worker!=null)
		{
			thread=new Thread(worker);
			thread.start();
			setState(true);
		}
    }
    
    public void stop() {if (worker!=null) worker.stopCond();}
    
    
    public void seek(int percent)
    {
    	if (worker!=null) { 
    		this.stop();
    		try {
    			thread.join(10*1000/this.message_rate);
    		} catch (InterruptedException e) {}
    		try {
    			synchronized(this)
    			{
    				in.seek(percent*in.getChannel().size()/100);
    				in.readLine();
    			}
    		} catch (IOException e) {}
    		this.run();
    	}    	
    }
    
    public void rewind() 
    {
    	seek(0);
    }
    public void setMsgRate(int newRate)
    { if (message_rate>0) message_rate=newRate;	}
    
}
